<template>
  <transition @enter="messageEnter" @after-enter="messageAfterEnter" @leave="messageLeave">
    <div v-if="visible" class="system-message" ref="systemMessageDom">
      <div class="message-inner">
        <i class="iconfont pb10" :class="[`wos-${type}`]" />
        <div class="title fs18 fw600 pb5" v-if="title">{{ title }}</div>
        <div class="content fs14" v-if="content">{{ content }}</div>
        <div class="system-message-btn" @click="handleCloseMessage">确定</div>
      </div>
    </div>
  </transition>
</template>

<script lang="ts">
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
import { getZIndex, prefixStyle, sleep } from '@/utils/utils'
import mitt from 'mitt'
import type { Emitter } from 'mitt'
import type { PropType } from 'vue'
import type { EmitterType, IMessageType } from '@/base/systemMessage/systemMessageInstance'

export default defineComponent({
  name: 'systemMessage',
  props: {
    type: {
      type: String as PropType<IMessageType>,
      default: 'warning'
    },
    title: {
      type: String as PropType<string>,
      default: ''
    },
    content: {
      type: String as PropType<string>,
      default: ''
    }
  },
  emits: ['close'],
  setup() {
    const Transform = prefixStyle('transform') as number
    const Transition = prefixStyle('transition') as number
    const systemMessageDom = ref<HTMLElement>()
    const messageAnimationTime = ref<number>(500)
    const visible = ref<boolean>(false)
    const messageMitt: Emitter<EmitterType> = mitt()

    // 关闭消息
    const handleCloseMessage = async () => {
      visible.value = false
      await sleep(messageAnimationTime.value)
      messageMitt.emit('close')
    }

    // 消息动画进入
    const messageEnter = (el: Element) => {
      const dom = el as HTMLElement
      dom.style.zIndex = `${getZIndex()}`
      dom.style.left = `${(innerWidth - dom.scrollWidth) / 2}px`
      dom.style.top = `${(innerHeight - dom.scrollHeight) / 2}px`
      dom.style[Transition] = `transform ${messageAnimationTime.value}ms cubic-bezier(0.175, 0.885, 0.32, 1.275)`
      dom.style[Transform] = 'translateZ(100px) rotateX(-90deg)'
    }

    // 消息动画进入后
    const messageAfterEnter = (el: Element) => {
      const dom = el as HTMLElement
      dom.style[Transition] = ``
    }

    // 消息动画进入
    const messageLeave = (el: Element) => {
      const dom = el as HTMLElement
      dom.style[Transition] = `transform ${messageAnimationTime.value}ms`
      dom.style[Transform] = 'translateZ(100px) rotateX(0deg)'
    }

    onMounted(async () => {
      await nextTick()
      visible.value = true
    })

    onBeforeUnmount(() => {
      messageMitt.off('close')
    })

    return {
      visible,
      getZIndex,
      messageMitt,
      systemMessageDom,
      messageAnimationTime,
      messageEnter,
      messageAfterEnter,
      messageLeave,
      handleCloseMessage
    }
  }
})
</script>

<style scoped lang="scss">
@import '@/assets/scss/common';

.system-message {
  position: fixed;
  transform-origin: center center;
  transform-style: preserve-3d;
  transform: translateZ(100px) rotateX(0deg);

  .message-inner {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 20px 30px;
    max-width: 360px;
    box-sizing: border-box;
    color: var(--message-modal-color);
    background-color: var(--message-modal-bg-color);
    border-radius: $message-modal-radius;
    transform-origin: center center;
    transform: translateY(-100px) rotateX(90deg);

    .wos-warning {
      font-size: 60px;
      background: linear-gradient(-135deg, rgb(240, 225, 0), rgb(226, 160, 8));
      background-clip: text;
      color: transparent;
    }

    .system-message-btn {
      cursor: pointer;
      margin-top: 20px;
      width: 100%;
      height: 32px;
      border-radius: 6px;
      font-size: 14px;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: rgb(25, 119, 218);
    }
  }
}
</style>
